using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Common;
using Common.Enum;
using Common.NotifyEvent;

namespace SExperiment
{
    [Serializable]
    public class ProjectStdCurve : NotifyPropertyChanged
    {
        private string _ProjectName;

        private EProjectType _Type;

        private bool _External;

        private string _Path;

        private List<Well> _ExternalStdWell;

        private string _Version;

        private List<TargetStdCurve> _ExternalTargetStdCurveList;

        private List<TargetStdCurve> _TargetStdCurveList;

        public string ProjectName
        {
            get
            {
                return _ProjectName;
            }
            set
            {
                if (!(_ProjectName == value))
                {
                    _ProjectName = value;
                    OnPropertyChanged("ProjectName");
                }
            }
        }

        public EProjectType Type
        {
            get
            {
                return _Type;
            }
            set
            {
                if (_Type != value)
                {
                    _Type = value;
                    OnPropertyChanged("Type");
                }
            }
        }

        public bool External
        {
            get
            {
                return _External;
            }
            set
            {
                if (_External != value)
                {
                    _External = value;
                    if (!_External)
                    {
                        Path = null;
                        ExternalStdWell = null;
                        ExternalTargetStdCurveList = null;
                        Version = null;
                    }
                    OnPropertyChanged("External");
                }
            }
        }

        public string Path
        {
            get
            {
                return _Path;
            }
            set
            {
                if (!(_Path == value))
                {
                    _Path = value;
                    OnPropertyChanged("Path");
                }
            }
        }

        public List<Well> ExternalStdWell
        {
            get
            {
                return _ExternalStdWell;
            }
            set
            {
                if (_ExternalStdWell != value)
                {
                    _ExternalStdWell = value;
                    OnPropertyChanged("ExternalStdWell");
                }
            }
        }

        public string Version
        {
            get
            {
                return _Version;
            }
            set
            {
                if (!(_Version == value))
                {
                    _Version = value;
                    OnPropertyChanged("Version");
                }
            }
        }

        public List<TargetStdCurve> ExternalTargetStdCurveList
        {
            get
            {
                return _ExternalTargetStdCurveList;
            }
            set
            {
                if (_ExternalTargetStdCurveList != value)
                {
                    _ExternalTargetStdCurveList = value;
                    OnPropertyChanged("ExternalTargetStdCurveList");
                }
            }
        }

        public List<TargetStdCurve> TargetStdCurveList
        {
            get
            {
                return _TargetStdCurveList;
            }
            set
            {
                if (_TargetStdCurveList != value)
                {
                    _TargetStdCurveList = value;
                    OnPropertyChanged("TargetStdCurveList");
                }
            }
        }

        public TargetStdCurve GetItem(string targetName)
        {
            if (TargetStdCurveList == null)
            {
                return null;
            }
            List<TargetStdCurve> list = TargetStdCurveList.Where((TargetStdCurve s) => s.TargetName == targetName).ToList();
            if (list.Count == 1)
            {
                return list[0];
            }
            return null;
        }

        public ProjectStdCurve Clone()
        {
            ProjectStdCurve projectStdCurve = new ProjectStdCurve();
            StreamEx streamEx = new StreamEx();
            SaveToStream(streamEx);
            streamEx.Seek(0L, SeekOrigin.Begin);
            projectStdCurve.ReadFromStream(streamEx);
            streamEx.Close();
            return projectStdCurve;
        }

        public bool Read(string file)
        {
            bool result = false;
            FileStream fileStream = null;
            StreamEx streamEx = new StreamEx();
            try
            {
                fileStream = new FileStream(file, FileMode.Open, FileAccess.Read);
                fileStream.CopyTo(streamEx);
                streamEx.Seek(0L, SeekOrigin.Begin);
                result = ReadFromStream(streamEx);
                Path = file;
            }
            catch (Exception)
            {
            }
            finally
            {
                if (streamEx != null)
                {
                    streamEx.Close();
                }
                if (fileStream != null)
                {
                    fileStream.Close();
                }
            }
            return result;
        }

        public void Save(string file)
        {
            FileStream fileStream = null;
            StreamEx streamEx = new StreamEx();
            try
            {
                fileStream = new FileStream(file, FileMode.Create, FileAccess.Write);
                SaveToStream(streamEx);
                streamEx.Seek(0L, SeekOrigin.Begin);
                streamEx.CopyTo(fileStream);
            }
            catch (Exception)
            {
            }
            finally
            {
                if (streamEx != null)
                {
                    streamEx.Close();
                }
                if (fileStream != null)
                {
                    fileStream.Close();
                }
            }
        }

        public void SaveToStream(StreamEx stream)
        {
            stream.Write(PropertyKey.Key_ProjectStdCurve);
            List<PropertyKey> list = new List<PropertyKey>();
            List<byte[]> list2 = new List<byte[]>();
            list.Add(PropertyKey.Key_Type);
            list2.Add(BytesConverter.GetBytes((int)Type));
            if (!string.IsNullOrEmpty(ProjectName))
            {
                list.Add(PropertyKey.Key_Name);
                list2.Add(BytesConverter.GetBytes(ProjectName));
            }
            list.Add(PropertyKey.Key_External);
            list2.Add(BytesConverter.GetBytes(External));
            if (!string.IsNullOrEmpty(Path))
            {
                list.Add(PropertyKey.Key_Path);
                list2.Add(BytesConverter.GetBytes(Path));
            }
            if (!string.IsNullOrEmpty(Version))
            {
                list.Add(PropertyKey.Key_Version);
                list2.Add(BytesConverter.GetBytes(Version));
            }
            if (ExternalStdWell != null)
            {
                StreamEx streamEx = new StreamEx();
                List<Well> externalStdWell = ExternalStdWell;
                streamEx.Write(externalStdWell.Count);
                Experiment.SaveToStreamWells(externalStdWell, streamEx, true);
                list.Add(PropertyKey.Key_ExternalStdWell);
                list2.Add(streamEx.ToArray());
                streamEx.Close();
            }
            if (ExternalTargetStdCurveList != null)
            {
                StreamEx streamEx2 = new StreamEx();
                streamEx2.Write(ExternalTargetStdCurveList.Count);
                foreach (TargetStdCurve externalTargetStdCurve in ExternalTargetStdCurveList)
                {
                    externalTargetStdCurve.SaveToStream(streamEx2);
                }
                list.Add(PropertyKey.Key_ExternalTargetStdCurveList);
                list2.Add(streamEx2.ToArray());
                streamEx2.Close();
            }
            if (TargetStdCurveList != null)
            {
                StreamEx streamEx3 = new StreamEx();
                streamEx3.Write(TargetStdCurveList.Count);
                foreach (TargetStdCurve targetStdCurve in TargetStdCurveList)
                {
                    targetStdCurve.SaveToStream(streamEx3);
                }
                list.Add(PropertyKey.Key_TargetStdCurveList);
                list2.Add(streamEx3.ToArray());
                streamEx3.Close();
            }
            stream.Write(PropertyKey.Key_Index);
            stream.WriteIndex(list, list2);
            stream.Flush();
        }

        public bool ReadFromStream(StreamEx stream)
        {
            PropertyKey propertyKey = stream.ReadKey();
            if (propertyKey == PropertyKey.Key_ProjectStdCurve)
            {
                propertyKey = stream.ReadKey();
                if (propertyKey == PropertyKey.Key_Index)
                {
                    List<PropertyKey> keys;
                    List<byte[]> dates;
                    stream.ReadIndex(out keys, out dates);
                    for (int i = 0; i < keys.Count; i++)
                    {
                        switch (keys[i])
                        {
                            case PropertyKey.Key_Type:
                                Type = (EProjectType)BytesConverter.BytesToInt(dates[i]);
                                break;
                            case PropertyKey.Key_Name:
                                ProjectName = BytesConverter.BytesToString(dates[i]);
                                break;
                            case PropertyKey.Key_External:
                                External = BytesConverter.BytesToBool(dates[i]);
                                break;
                            case PropertyKey.Key_Path:
                                Path = BytesConverter.BytesToString(dates[i]);
                                break;
                            case PropertyKey.Key_Version:
                                Version = BytesConverter.BytesToString(dates[i]);
                                break;
                            case PropertyKey.Key_ExternalStdWell:
                                {
                                    StreamEx streamEx = new StreamEx();
                                    streamEx.Write(dates[i]);
                                    streamEx.Seek(0L, SeekOrigin.Begin);
                                    int num = streamEx.ReadInt();
                                    List<Well> list = new List<Well>();
                                    for (int l = 0; l < num; l++)
                                    {
                                        list.Add(new Well());
                                    }
                                    Experiment.ReadFromStreamWells(list, streamEx);
                                    ExternalStdWell = list;
                                    streamEx.Close();
                                    break;
                                }
                            case PropertyKey.Key_ExternalTargetStdCurveList:
                                {
                                    StreamEx streamEx = new StreamEx();
                                    streamEx.Write(dates[i]);
                                    streamEx.Seek(0L, SeekOrigin.Begin);
                                    int num = streamEx.ReadInt();
                                    ExternalTargetStdCurveList = new List<TargetStdCurve>();
                                    for (int k = 0; k < num; k++)
                                    {
                                        TargetStdCurve targetStdCurve2 = new TargetStdCurve();
                                        targetStdCurve2.ReadFromStream(streamEx);
                                        ExternalTargetStdCurveList.Add(targetStdCurve2);
                                    }
                                    streamEx.Close();
                                    break;
                                }
                            case PropertyKey.Key_TargetStdCurveList:
                                {
                                    StreamEx streamEx = new StreamEx();
                                    streamEx.Write(dates[i]);
                                    streamEx.Seek(0L, SeekOrigin.Begin);
                                    int num = streamEx.ReadInt();
                                    TargetStdCurveList = new List<TargetStdCurve>();
                                    for (int j = 0; j < num; j++)
                                    {
                                        TargetStdCurve targetStdCurve = new TargetStdCurve();
                                        targetStdCurve.ReadFromStream(streamEx);
                                        TargetStdCurveList.Add(targetStdCurve);
                                    }
                                    streamEx.Close();
                                    break;
                                }
                        }
                    }
                    return true;
                }
                stream.Seek(-4L, SeekOrigin.Current);
                return false;
            }
            bool flag = false;
            stream.Seek(-4L, SeekOrigin.Current);
            while (true)
            {
                switch (stream.ReadKey())
                {
                    case PropertyKey.Key_Type:
                        if (flag)
                        {
                            stream.Seek(-4L, SeekOrigin.Current);
                            return true;
                        }
                        flag = true;
                        Type = (EProjectType)stream.ReadInt();
                        break;
                    case PropertyKey.Key_Name:
                        ProjectName = stream.ReadString();
                        break;
                    case PropertyKey.Key_External:
                        External = stream.ReadBool();
                        break;
                    case PropertyKey.Key_Path:
                        Path = stream.ReadString();
                        break;
                    case PropertyKey.Key_Version:
                        Version = stream.ReadString();
                        break;
                    case PropertyKey.Key_ExternalStdWell:
                        {
                            int num2 = stream.ReadInt();
                            List<Well> list2 = new List<Well>();
                            for (int num3 = 0; num3 < num2; num3++)
                            {
                                list2.Add(new Well());
                            }
                            Experiment.ReadFromStreamWells(list2, stream);
                            ExternalStdWell = list2;
                            break;
                        }
                    case PropertyKey.Key_ExternalTargetStdCurveList:
                        {
                            int num2 = stream.ReadInt();
                            ExternalTargetStdCurveList = new List<TargetStdCurve>();
                            for (int n = 0; n < num2; n++)
                            {
                                TargetStdCurve targetStdCurve4 = new TargetStdCurve();
                                targetStdCurve4.ReadFromStream(stream);
                                ExternalTargetStdCurveList.Add(targetStdCurve4);
                            }
                            break;
                        }
                    case PropertyKey.Key_TargetStdCurveList:
                        {
                            int num2 = stream.ReadInt();
                            TargetStdCurveList = new List<TargetStdCurve>();
                            for (int m = 0; m < num2; m++)
                            {
                                TargetStdCurve targetStdCurve3 = new TargetStdCurve();
                                targetStdCurve3.ReadFromStream(stream);
                                TargetStdCurveList.Add(targetStdCurve3);
                            }
                            break;
                        }
                    default:
                        stream.Seek(-4L, SeekOrigin.Current);
                        return true;
                }
            }
        }
    }
}
